﻿//using System.Collections;
//using System.Collections.Generic;
//using UnityEngine;
//using Unity.Entities;
//using Unity.Mathematics;

//public static class TerrianAPI
//{
//    private const int _MAXBUFFERSIZE = 1000;
//    private static EntityManager mgr = MainGame.testManager;
//    private static DefaultBuffer defaultBuffer = new DefaultBuffer
//    {
//        dataCnt = 0,
//        defaultDataBuffer = new DataPack[_MAXBUFFERSIZE],
//        isOccupied = new bool[_MAXBUFFERSIZE]
//    };

//    public struct ID
//    {
//        public int waitNum;
//        public int[] idVector;
//        public ID(int x, int y, int z, int w)
//        {
//            this.waitNum = -1;
//            this.idVector = new int[5];
//            this.idVector[1] = x;
//            this.idVector[2] = y;
//            this.idVector[3] = z;
//            this.idVector[4] = w;
//        }
//        public static ID IDEncode(QData data)
//        {
//            var tmpID = new ID();
//            tmpID.idVector = new int[5];
//            tmpID.idVector[1] = data.belongToChunk.centerCoordInt.x;
//            tmpID.idVector[2] = data.belongToChunk.centerCoordInt.y;
//            tmpID.idVector[3] = data.coordInt.x;
//            tmpID.idVector[4] = data.coordInt.y;
//            tmpID.waitNum = -1;
//            return tmpID;
//        }
//        public static ID IDEncode(Vector3 coordWorld)
//        {
//            int[] ansV = new int[5];
//            coordWorld -= Chunk.CHUNKBASEPOINT;

//            Vector3 tmp = new Vector3(0, 0, 0);

//            tmp.x = (int)(coordWorld.x / TerrianQuadTree.CHUNKSIZE);
//            tmp.x = coordWorld.x > 0 ? tmp.x + 1 : tmp.x - 1;
//            tmp.y = (int)(coordWorld.y / TerrianQuadTree.CHUNKSIZE);
//            tmp.y = coordWorld.y > 0 ? tmp.y + 1 : tmp.y - 1;
//            ansV[1] = (int)tmp.x;
//            ansV[2] = (int)tmp.y;

//            tmp.x = tmp.x > 0 ? coordWorld.x - (tmp.x - 0.5f) * TerrianQuadTree.CHUNKSIZE : coordWorld.x - (tmp.x + 0.5f) * TerrianQuadTree.CHUNKSIZE;


//            tmp.y = tmp.y > 0 ? coordWorld.y - (tmp.y - 0.5f) * TerrianQuadTree.CHUNKSIZE : coordWorld.y - (tmp.y + 0.5f) * TerrianQuadTree.CHUNKSIZE;


//            tmp.x = tmp.x > 0 ? (int)(tmp.x / VoxelStatic.VOXELSIZE) + 1 : (int)(tmp.x / VoxelStatic.VOXELSIZE) - 1;
//            tmp.y = tmp.y > 0 ? (int)(tmp.y / VoxelStatic.VOXELSIZE) + 1 : (int)(tmp.y / VoxelStatic.VOXELSIZE) - 1;
//            ansV[3] = (int)tmp.x;
//            ansV[4] = (int)tmp.y;

//            return new ID { idVector = ansV, waitNum = -1 };
//        }

//        public static void IDDecode(ID id, out Chunk chunk, out int x, out int y)
//        {
//            chunk = MainGame.chunkList.Find(c => (c.centerCoordInt.x == id.idVector[1] && c.centerCoordInt.y == id.idVector[2]));
//            x = id.idVector[3];
//            y = id.idVector[4];
//        }
//        public static Vector3 IDToCoordWorld(ID id)
//        {
//            Vector3 ans = new Vector3(0, 0, 0);
//            ans.x = id.idVector[1] * TerrianQuadTree.CHUNKSIZE;
//            ans.x = ans.x > 0 ? ans.x - TerrianQuadTree.HALFCHUNKSIZE : ans.x + TerrianQuadTree.HALFCHUNKSIZE;
//            ans.x += id.idVector[3] * VoxelStatic.VOXELSIZE;
//            ans.x = id.idVector[3] > 0 ? ans.x - VoxelStatic.HALFVOXELSIZE : ans.x + VoxelStatic.HALFVOXELSIZE;

//            ans.y = id.idVector[2] * TerrianQuadTree.CHUNKSIZE;
//            ans.y = ans.y > 0 ? ans.y - TerrianQuadTree.HALFCHUNKSIZE : ans.y + TerrianQuadTree.HALFCHUNKSIZE;
//            ans.y += id.idVector[4] * VoxelStatic.VOXELSIZE;
//            ans.y = id.idVector[4] > 0 ? ans.y - VoxelStatic.HALFVOXELSIZE : ans.y + VoxelStatic.HALFVOXELSIZE;

//            ans += Chunk.CHUNKBASEPOINT;
//            return ans;
//        }
//    }

//    public struct DataPack
//    {
//        public Vector3 coord;
//        public Vector3Int coordInt;
//        public Chunk belongToChunk;
//        public TerrianAPI.ID id;
//        public VoxelComponentData vData;
//    }

//    private struct DefaultBuffer
//    {
//        public DataPack[] defaultDataBuffer;
//        public bool[] isOccupied;
//        public int dataCnt;
//    }

//    /// <summary>
//    /// 查询一个体素
//    /// </summary>
//    /// <param name="chunk"></param>
//    /// <param name="x"></param>
//    /// <param name="y"></param>
//    /// <param name="toCreate"></param>
//    /// <returns></returns>
//    public static DataPack GetInfo(ID id)
//    {
//        if (id.waitNum != -1)
//        {
//            Debug.LogWarning("正在查询未设定的Voxel");
//            return new DataPack { id = id };
//        }
//        ID.IDDecode(id, out Chunk chunkToAcess, out int x, out int y);
//        var node = chunkToAcess.quadTreeInternal.rootNode.Search(new Vector3(x, y, 0));
//        if (node == null || chunkToAcess == null)
//        {
//            Debug.LogError("查询的Voxel不存在");
//        }
//        var toGet = node.EntityStore.Find(d => d.coord == new Vector3(x, y, 0));
//        return new DataPack
//        {
//            belongToChunk = chunkToAcess,
//            coord = toGet.coord,
//            coordInt = toGet.coordInt,
//            id = id,
//            vData = mgr.GetComponentData<VoxelComponentData>(toGet.entityData)
//        };
//    }

//    /// <summary>
//    /// 查询一个Entity
//    /// </summary>
//    /// <param name="id"></param>
//    /// <returns></returns>
//    public static Entity GetEntity(ID id)
//    {
//        ID.IDDecode(id, out Chunk chunkToAcess, out int x, out int y);
//        var node = chunkToAcess.quadTreeInternal.rootNode.Search(new Vector3(x, y, 0));
//        if (node == null || chunkToAcess == null)
//        {
//            Debug.LogError("查询的Voxel不存在");
//        }
//        return node.EntityStore.Find(d => d.coord == new Vector3(x, y, 0)).entityData;
//    }


//    /// <summary>
//    /// 设置某id的体素的数据，注意坐标数据不会被实际修改
//    /// </summary>
//    /// <param name="id"></param>
//    /// <param name="toSet"></param>
//    public static void SetInfo(ID id, DataPack toSet)
//    {
//        if (id.waitNum != -1)
//        {
//            defaultBuffer.dataCnt--;
//            defaultBuffer.defaultDataBuffer[id.waitNum] = default;
//            defaultBuffer.isOccupied[id.waitNum] = false;
//            Create(toSet.id, VoxelStatic.voxelValues[(int)toSet.vData.elem], false);
//            MainGame.testValueChange.Enqueue(new SetChangeClass { id = id, toSet = toSet });
//        }
//        else
//        {
//            Entity eToSet = GetEntity(id);
//            mgr.SetComponentData<VoxelComponentData>(eToSet, toSet.vData);
//            MainGame.testValueChange.Enqueue(new SetChangeClass { id = id, toSet = toSet });
//        }
//    }


//    /// <summary>
//    /// 不暴露的Create
//    /// </summary>
//    private static void Create(Chunk chunk, float x, float y, Voxel toCreate)
//    {
//        if (((x % VoxelStatic.HALFVOXELSIZE) != 0) || ((y % VoxelStatic.HALFVOXELSIZE) != 0))
//        {
//            Debug.LogError("Voxel不对齐，生成不合法");
//            return;
//        }
//        int tmpX = (int)(x / VoxelStatic.HALFVOXELSIZE);
//        int tmpY = (int)(y / VoxelStatic.HALFVOXELSIZE);
//        if ((tmpX % 2 == 0) || (tmpY % 2 == 0))
//        {
//            Debug.LogError("Voxel不对齐，生成不合法");
//            return;
//        }
//        if (x - chunk.centerCoord.x >= TerrianQuadTree.HALFCHUNKSIZE - VoxelStatic.HALFVOXELSIZE || x - chunk.centerCoord.x <= -(TerrianQuadTree.HALFCHUNKSIZE - VoxelStatic.HALFVOXELSIZE))
//        {
//            Debug.LogError("Voxel越界，生成不合法");
//            return;
//        }
//        if (y - chunk.centerCoord.y >= TerrianQuadTree.HALFCHUNKSIZE - VoxelStatic.HALFVOXELSIZE || y - chunk.centerCoord.y <= -(TerrianQuadTree.HALFCHUNKSIZE - VoxelStatic.HALFVOXELSIZE))
//        {
//            Debug.LogError("Voxel越界，生成不合法");
//            return;
//        }
//        Entity newVoxelEntity = VoxelStatic.Spawn(World.DefaultGameObjectInjectionWorld.EntityManager, x + chunk.centerCoord.x, y + chunk.centerCoord.y, toCreate);
//        QData newData = new QData();
//        newData.coordInt.x = tmpX > 0 ? (tmpX + 1) / 2 : (tmpX - 1) / 2;
//        newData.coordInt.y = tmpY > 0 ? (tmpY + 1) / 2 : (tmpY - 1) / 2;
//        newData.coord.x = x;
//        newData.coord.y = y;
//        newData.entityData = newVoxelEntity;
//        newData.belongToChunk = chunk;
//        newData.id = ID.IDEncode(newData);
//        if (chunk.quadTreeInternal.rootNode != null)
//        {
//            chunk.quadTreeInternal.rootNode.Insert(newData);
//        }
//        MainGame.testValueChange.Enqueue(
//                    new AddChangeClass
//                    {
//                        addData = new DataPack
//                        {
//                            belongToChunk = chunk,
//                            coord = new Vector3(x, y, 0),
//                            coordInt = new Vector3Int(tmpX, tmpY, 0),
//                            id = newData.id,
//                            vData = mgr.GetComponentData<VoxelComponentData>(newVoxelEntity)
//                        }
//                    });
//    }

//    private static void Create(Chunk chunk, float x, float y, Voxel toCreate, bool isRecorded)
//    {
//        if (((x % VoxelStatic.HALFVOXELSIZE) != 0) || ((y % VoxelStatic.HALFVOXELSIZE) != 0))
//        {
//            Debug.LogError("Voxel不对齐，生成不合法");
//            return;
//        }
//        int tmpX = (int)(x / VoxelStatic.HALFVOXELSIZE);
//        int tmpY = (int)(y / VoxelStatic.HALFVOXELSIZE);
//        if ((tmpX % 2 == 0) || (tmpY % 2 == 0))
//        {
//            Debug.LogError("Voxel不对齐，生成不合法");
//            return;
//        }
//        if (x >= TerrianQuadTree.HALFCHUNKSIZE - VoxelStatic.HALFVOXELSIZE || x <= -(TerrianQuadTree.HALFCHUNKSIZE - VoxelStatic.HALFVOXELSIZE))
//        {
//            Debug.LogError("Voxel越界，生成不合法");
//            return;
//        }
//        if (y >= TerrianQuadTree.HALFCHUNKSIZE - VoxelStatic.HALFVOXELSIZE || y <= -(TerrianQuadTree.HALFCHUNKSIZE - VoxelStatic.HALFVOXELSIZE))
//        {
//            Debug.LogError("Voxel越界，生成不合法");
//            return;
//        }
//        Entity newVoxelEntity = VoxelStatic.Spawn(World.DefaultGameObjectInjectionWorld.EntityManager, x + chunk.centerCoord.x, y + chunk.centerCoord.y, toCreate);
//        QData newData = new QData();
//        newData.coordInt.x = tmpX > 0 ? (tmpX + 1) / 2 : (tmpX - 1) / 2;
//        newData.coordInt.y = tmpY > 0 ? (tmpY + 1) / 2 : (tmpY - 1) / 2;
//        newData.coord.x = x;
//        newData.coord.y = y;
//        newData.entityData = newVoxelEntity;
//        newData.belongToChunk = chunk;
//        newData.id = ID.IDEncode(newData);
//        if (chunk.quadTreeInternal.rootNode != null)
//        {
//            chunk.quadTreeInternal.rootNode.Insert(newData);
//        }
//        if (isRecorded)
//        {
//            MainGame.testValueChange.Enqueue(
//                    new AddChangeClass
//                    {
//                        addData = new DataPack
//                        {
//                            belongToChunk = chunk,
//                            coord = new Vector3(x, y, 0),
//                            coordInt = new Vector3Int(tmpX, tmpY, 0),
//                            id = newData.id,
//                            vData = mgr.GetComponentData<VoxelComponentData>(newVoxelEntity)
//                        }
//                    });
//        }
//    }

//    /// <summary>
//    /// 不暴露的Create
//    /// </summary>
//    [System.Obsolete]
//    private static void Create(Chunk chunk, int x, int y, Voxel toCreate)
//    {
//        float xx = chunk.centerCoord.x + x * VoxelStatic.VOXELSIZE;
//        xx = xx >= 0 ? xx - VoxelStatic.HALFVOXELSIZE : xx + VoxelStatic.HALFVOXELSIZE;
//        float yy = chunk.centerCoord.y + y * VoxelStatic.VOXELSIZE;
//        yy = yy >= 0 ? yy - VoxelStatic.HALFVOXELSIZE : yy + VoxelStatic.HALFVOXELSIZE;
//        if (!chunk.chunkBound.Contains(new Vector3(xx, yy, 0)))
//        {
//            Debug.LogError("插入Voxel在对应Chunk出界");
//        }
//        Entity newVoxelEntity = VoxelStatic.Spawn(World.DefaultGameObjectInjectionWorld.EntityManager, xx, yy, toCreate);
//        QData newData = new QData();
//        newData.coordInt.x = x;
//        newData.coordInt.y = y;
//        newData.coord.x = xx;
//        newData.coord.y = yy;
//        newData.entityData = newVoxelEntity;
//        newData.belongToChunk = chunk;
//        newData.id = ID.IDEncode(newData);
//        if (chunk.quadTreeInternal.rootNode != null)
//        {
//            chunk.quadTreeInternal.rootNode.Insert(newData);
//        }
//        MainGame.testValueChange.Enqueue(
//                    new AddChangeClass
//                    {
//                        addData = new DataPack
//                        {
//                            belongToChunk = chunk,
//                            coord = new Vector3(xx, yy, 0),
//                            coordInt = new Vector3Int(x, y, 0),
//                            id = newData.id,
//                            vData = mgr.GetComponentData<VoxelComponentData>(newVoxelEntity)
//                        }
//                    });
//    }

//    /// <summary>
//    /// 同上，可以指定是否记录在队列中
//    /// </summary>
//    private static void Create(Chunk chunk, int x, int y, Voxel toCreate, bool isRecorded)
//    {
//        float xx = chunk.centerCoord.x + x * VoxelStatic.VOXELSIZE;
//        xx = xx >= 0 ? xx - VoxelStatic.HALFVOXELSIZE : xx + VoxelStatic.HALFVOXELSIZE;
//        float yy = chunk.centerCoord.y + y * VoxelStatic.VOXELSIZE;
//        yy = yy >= 0 ? yy - VoxelStatic.HALFVOXELSIZE : yy + VoxelStatic.HALFVOXELSIZE;
//        if (!chunk.chunkBound.Contains(new Vector3(xx, yy, 0)))
//        {
//            Debug.LogError("插入Voxel在对应Chunk出界");
//        }
//        Entity newVoxelEntity = VoxelStatic.Spawn(World.DefaultGameObjectInjectionWorld.EntityManager, xx, yy, toCreate);
//        QData newData = new QData();
//        newData.coordInt.x = x;
//        newData.coordInt.y = y;
//        newData.coord.x = xx;
//        newData.coord.y = yy;
//        newData.entityData = newVoxelEntity;
//        newData.belongToChunk = chunk;
//        newData.id = ID.IDEncode(newData);
//        if (chunk.quadTreeInternal.rootNode != null)
//        {
//            chunk.quadTreeInternal.rootNode.Insert(newData);
//        }
//        if (isRecorded)
//        {
//            MainGame.testValueChange.Enqueue(
//            new AddChangeClass
//            {
//                addData = new DataPack
//                {
//                    belongToChunk = chunk,
//                    coord = new Vector3(xx, yy, 0),
//                    coordInt = new Vector3Int(x, y, 0),
//                    id = newData.id,
//                    vData = mgr.GetComponentData<VoxelComponentData>(newVoxelEntity)
//                }
//            });
//        }
//    }


//    /// <summary>
//    /// 不暴露的Create
//    /// </summary>
//    [System.Obsolete]
//    private static void Create(Chunk chunk, Vector2 v, Voxel toCreate)
//    {
//        Create(chunk, v.x, v.y, toCreate);
//    }


//    /// <summary>
//    /// 创建一个指定id的Voxel
//    /// </summary>
//    /// <param name="id"></param>
//    /// <param name="toCreate"></param>
//    public static void Create(ID id, Voxel toCreate)
//    {
//        Chunk c = MainGame.chunkList.Find(cc => (cc.centerCoordInt.x == id.idVector[1] && cc.centerCoordInt.y == id.idVector[2]));
//        if (c == null)
//        {
//            c = new Chunk(new Vector3Int(id.idVector[1], id.idVector[2], 0));
//        }
//        var coordWorld = ID.IDToCoordWorld(id);
//        Create(c, coordWorld.x, coordWorld.y, toCreate);
//    }

//    /// <summary>
//    /// 创建一个指定id的Voxel，可以指定是否记录在队列中
//    /// </summary>
//    /// <param name="id"></param>
//    /// <param name="toCreate"></param>
//    public static void Create(ID id, Voxel toCreate, bool isRecorded)
//    {
//        Chunk c = MainGame.chunkList.Find(cc => (cc.centerCoordInt.x == id.idVector[1] && cc.centerCoordInt.y == id.idVector[2]));
//        if (c == null)
//        {
//            c = new Chunk(new Vector3Int(id.idVector[1], id.idVector[2], 0));
//        }
//        var coordWorld = ID.IDToCoordWorld(id);
//        Create(c, coordWorld.x, coordWorld.y, toCreate, isRecorded);
//    }

//    /// <summary>
//    /// 创建一个缺省的Voxel存储在Buffer中
//    /// </summary>
//    /// <returns></returns>
//    public static ID Create()
//    {
//        DataPack tmp = new DataPack();
//        int p = 1;
//        while (defaultBuffer.isOccupied[p] == false && p < _MAXBUFFERSIZE)
//        {
//            p++;
//        }
//        if (p >= _MAXBUFFERSIZE)
//        {
//            Debug.LogError("Buffer溢出");
//        }
//        tmp.id = new ID { waitNum = p };
//        defaultBuffer.defaultDataBuffer[p] = tmp;
//        defaultBuffer.isOccupied[p] = true;
//        defaultBuffer.dataCnt++;
//        return tmp.id;
//    }

//    /// <summary>
//    /// 不暴露的Delete
//    /// </summary>
//    private static void Delete(Chunk chunk, Vector3Int toDel)
//    {
//        if (chunk == null)
//        {
//            Debug.LogError("删除的Chunk不存在");
//        }
//        Vector3 tmp = new Vector3();
//        tmp.x = chunk.centerCoord.x + (toDel.x - 0.5f) * VoxelStatic.VOXELSIZE;
//        tmp.y = chunk.centerCoord.y + (toDel.y - 0.5f) * VoxelStatic.VOXELSIZE;
//        tmp.z = 0;
//        chunk.quadTreeInternal.rootNode.Delete(tmp);
//    }
//    public static void Delete(ID id)
//    {
//        ID.IDDecode(id, out Chunk c, out int x, out int y);
//        Delete(c, new Vector3Int(x, y, 0));
//        MainGame.testValueChange.Enqueue(new DeleteChangeClass { id = id });
//    }

//    /// <summary>
//    /// 获取一帧内的变化信息
//    /// </summary>
//    /// <returns></returns>
//    public static ValueChange GetChangedInfo()
//    {
//        return MainGame.testValueChange;
//    }


//    /// <summary>
//    /// 应用一系列的变化
//    /// </summary>
//    /// <param name="changed"></param>
//    public static void ApplyChangedInfo(List<ChangeClass> changed)
//    {
//        MainGame.testValueChange = new ValueChange(changed);
//        MainGame.testValueChange.Conduct();
//    }


//    /// <summary>
//    /// 获取所有体素数据，开销很大
//    /// </summary>
//    /// <returns></returns>
//    public static List<DataPack> GetAllData()
//    {
//        List<DataPack> ans = new List<DataPack>();
//        foreach (var chunk in MainGame.chunkList)
//        {
//            var qDatas = chunk.quadTreeInternal.GetAllSubData(chunk.quadTreeInternal.rootNode);
//            foreach (var qd in qDatas)
//            {
//                ans.Add(new DataPack
//                {
//                    belongToChunk = chunk,
//                    coord = qd.coord,
//                    coordInt = qd.coordInt,
//                    id = qd.id,
//                    vData = mgr.GetComponentData<VoxelComponentData>(qd.entityData)
//                });
//            }
//        }
//        return ans;
//    }


//    /// <summary>
//    /// 设置所有数据，开销很大
//    /// </summary>
//    /// <param name="toSet"></param>
//    public static void SetAllData(List<DataPack> toSet)
//    {
//        foreach (var d in toSet)
//        {
//            SetInfo(d.id, d);
//        }
//    }

//    public static List<ID> GetOverlapInfo(Geo.GeoArea area)
//    {
//        var overlapSys = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<AreaOverlapSystem>();
//        MainGame.overlapList = new List<ID>();

//        overlapSys.OverlapFilt(area);
//        return MainGame.overlapList;
//    }
//}
